Practice | GeeksforGeeks | A computer science portal for geeks
LIVE   BATCHES
We have combined Classroom and Theory tab and created a new Learn tab for easy access. You can access Classroom and Theory from the left panel.

Introduction to Arrays in C++

Declaring and Initializing Arrays

Size of An Array in C++

Array Traversal in C++

Different Types of Arrays 

Sum of an Array

Maximum in an Array

Applications of Pointers in C++

This video talks about different methods to create multidimensional arrays in C++
Codes:


This video talks about challenges we face when we pass multidimensional arrays as arguments.
Codes:


String in C++ (Introduction)

String: Binary To Decimal

String: Decimal To Binary
An array is collection of items stored at continuous memory locations. In Arrays, all elements stored must be of same data type. In other words, we can also define an array as a set of elements of same data type stored linearly at contigous memory locations.

arrays

Why do we need arrays? We can use normal variables (v1, v2, v3, ..) when we have a small number of objects, but if we want to store a large number of instances, it becomes difficult to manage them with normal variables. The idea of an array is to represent many instances in one variable.

Array declaration in C/C++:



We can declare an array by specifying its type and size or by initializing it or by both.

  1. Array declaration by specifying size
    int arr[10]; //array declaration with specific size
    int n;
    cin >> n;
    int arr[n]; //declare array after user-input
    הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

  2. Array declaration by initializing elements
    // Array declaration by initializing elements
    int arr[] = { 10, 20, 30, 40 }
    // Compiler creates an array of size 4.
    // above is same as "int arr[4] = {10, 20, 30, 40}"
    הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

  3. Array declaration by specifying size and initializing elements
    // Array declaration by specifying size and initializing
    // elements
    int arr[6] = { 10, 20, 30, 40 }
    // Compiler creates an array of size 6, initializes first
    // 4 elements as specified by user and rest two elements as 0.
    // above is same as "int arr[] = {10, 20, 30, 40, 0, 0}"
    הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX


Facts about Array in C/C++:
  • Accessing Array Elements: Array elements are accessed by using an integer index. Array index starts with 0 and goes till size of array minus 1.



    The following are a few examples.

    #include <bits/stdc++.h>
    using namespace std;
    int main()
    {
    int arr[5];
    arr[0] = 5;
    arr[2] = -10;
    arr[3 / 2] = 2; // this is same as arr[1] = 2
    arr[3] = arr[0];
    cout << arr[0] << arr[1] << arr[2] << arr[3];
    return 0;
    }
    הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    Output:
    5 2 -10 5


  • No Index Out of bound Checking: There is no index out of bound checking in C/C++, for example the following program compiles fine but may produce unexpected output when run.

    // This C++ program compiles fine
    // as index out of bound
    // is not checked in C++.
    #include <bits/stdc++.h>
    using namespace std;
    int main()
    {
    int arr[2];
    cout << arr[3] << " " << arr[-2] << " ";
    return 0;
    }
    הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    Output:
    2008101287 4195777
  • Contiguous Allocation in Arrays:
    Below program demonstrates the fact that array elements are allocated in a contiguous fashion.
    #include <bits/stdc++.h>
    using namespace std;
    int main()
    {
    // an array of 10 integers. If arr[0] is stored at
    // address x, then arr[1] is stored at x + sizeof(int)
    // arr[2] is stored at x + sizeof(int) + sizeof(int)
    // and so on.
    int arr[5], i;
    cout <<"Size of int in this compiler is "<<sizeof(int)<<endl;
    for (i = 0; i < 5; i++)
    // The use of '&' before a variable name, yields
    // address of variable.
    cout <<"Address arr[" << i << "] is "<< &arr[i] <<endl;
    return 0;
    }
    הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    Output:
    Size of integer in this compiler is 4
    Address arr[0] is 0x7ffd636b4260
    Address arr[1] is 0x7ffd636b4264
    Address arr[2] is 0x7ffd636b4268
    Address arr[3] is 0x7ffd636b426c
    Address arr[4] is 0x7ffd636b4270

Till now, we have studied about Single-dimensional arrays only. We can create multi-dimensional arrays as well.

Multi-dimensional Arrays

//creates (size1 * size2) type 2-D matrix
int arr[size1][size2]

//creates (size1 * size2 * size3) type 2-D matrix
int arr[size1][size2][size3]
...
We can continue with as many dimensions as we like:
// (size1 * size2 * ... *size_n) matrix
int arr[size1][size2][size3]....[size_n]
A 2-d array and a 3-d array can be visualized as:
two-d

Initialization by directly assigning elements:
int arr[2][3] = { {0, 1, 2}, {3, 4, 5} };
int arr[2][3][4] =
{
{ {0, 1, 2, 3}, {4, 5, 6, 7}, {8, 9, 10, 11} },
{ {12, 13, 14, 15}, {16, 17, 18, 19}, {20, 21, 22, 23} }
};
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
To access a particular element, we do as:
arr[i][j];
arr[i][j][k];
There are mainly 2 ways of handling strings in C++. One is to use the native C-style strings or character arrays and the other is to use the string template class (available as part of C++ Standard Template Library).

C-style (character arrays and literals)

C-style strings are defined using character arrays. There is an extra character called the null (\0) character appended to the character array to mark it's end.

Syntax:
char str_name[size];

Declaration & Initialization of string
char str[size];
char str[] = "Geeks";
char str[5] = "Geeks";
char str[] = {'G','e','e','k','s'};
Below is the memory representation of a string "Geeks".

Input & Output C-style strings
#include <bits/stdc++.h>
using namespace std;
int main()
{
// Declared a string, str of max size 10
char str[10];
// Taking input from user
cin>>str;
// Printing the string
cout<<str<<endl;
return 0;
}
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Input: Hello
Output: Hello

There are some important C-style in-built string functions (standard provided) given below which are generally used for string manipulation:

Note: These functions are available in the header file cstring. Therefore, one must include the line #include< cstring > inorder to use these funcitons.

  • strlen: Finds the length of the string. This is especially useful when looping over each character in the string. As an example, in the below program we iterate over each character and convert them to uppercase.
    #include <bits/stdc++.h>
    using namespace std;
    int main()
    {
    char str[]="hello";
    for (int i=0;i<strlen(str);i++)
    cout<<(char)(str[i]-'a'+'A');
    return 0;
    }
    הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    Output:
    HELLO
  • strcat: Appends a copy of the source string to the end of destination string. Thus it takes two arguments, first is the destination, then source.
    #include <bits/stdc++.h>
    using namespace std;
    int main()
    {
    char src[] = "source";
    char dest[] = "destination";
    cout<<strcat(dest,src)<<endl;
    return 0;
    }
    הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    Output:
    destinationsource
  • strcmp: Performs lexicographical comparison between 2 strings. The function returns an integer.
    • = 0 (if both strings are equal)
    • > 0 (if 1st string appears after 2nd string in lexicographical order)
    • < 0 (if 1st string appears before 2nd string in lexicographical order
    #include <bits/stdc++.h>
    using namespace std;
    int main()
    {
    char str1[]="abc";
    char str2[]="abcd";
    char str3[]="abb";
    cout<<strcmp(str1,str2)<<endl;
    cout<<strcmp(str1,str3)<<endl;
    cout<<strcmp(str2,str3)<<endl;
    return 0;
    }
    הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    Output:
    -100   <0 indicating str1 appears before str2
    1 >0 indicating str1 appears after str3
    1 >0 indicating str2 appears after str3
  • strcpy: Copies source string to the destination string. Here also the 1st parameter is the destination string and the 2nd is the source string.
    #include <bits/stdc++.h>
    using namespace std;
    int main()
    {
    char dest[100];
    char src[]="Hello World";
    strcpy(dest, src);
    cout<<"Source: "<<src<<endl;
    cout<<"Destination: "<<dest<<endl;
    return 0;
    }
    הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    Output:
    Source: Hello World
    Destination: Hello World
  • strstr: Used for string searching. Finds and returns pointer to the first occurence of one string in another. Here also the 2nd string is searched in the1st string.
    #include <bits/stdc++.h>
    using namespace std;
    int main()
    {
    char s1[] = "GeeksforGeeks";
    char s2[] = "for";
    char *p;
    p = strstr(s1, s2);
    if (p)
    cout << "First occurrence of string '" << s2
    << "'\n in '" << s1 << "' is '" << p <<"'"<<endl;
    else
    cout << "String not found\n";
    return 0;
    }
    הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    Output:
    First occurrence of string 'for'
    in 'GeeksforGeeks' is 'forGeeks'

String Class in C++ STL


C++ STL (Standard Template Class) provides a more powerful string class implementation. string template implementation is better than native C-style character arrays in the following aspects.
C-style character array C++ string class
Array of characters terminated by null (\0) Class object instance storing stream of characters
Allocated Statically (can't be modified in run-time) Allocated Dynamically (modifiable at run-time)
Vulnerable to array decay Class-based implementation evades such vulnerabilities
Limited inbuilt functions for manipulation Rich inbuilt function support for manipulation

Syntax: Declaring strings using STL class is simpler than declaring character arrays.
string str_name;

Example:
#include <bits/stdc++.h>
using namespace std;
int main()
{
// Declaring String
string str;
// Taking input from user
cin>>str;
// Printing the String
cout<<str<<endl;
cout<<str.length()<<endl;
return 0;
}
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Input: Hello
Output: Hello
5

We can also declare and initialize a string at same time:
// Both of the below methods works fine:

Method 1:
string str = "This is a sample string"; // This is correct

Method 2:
string str;
str = "This is a sample string"; // This is also correct

Below are some of the most frequently used functions available in the std::string class which can be used for string manipulations. We need to understand an iterator first (in brief) to understand each of these string-class methods.

An iterator is an object (like a pointer) that points to an element inside the container. We can use iterators to move through the contents of the container. They can be visualized as something similar to a pointer pointing to some location and we can access the content at that particular location using them. Example usage of an iterator to print out the string is given below.
#include <bits/stdc++.h>
using namespace std;
int main()
{
string s = "GeeksforGeeks";
//declaration of iterator
string::iterator it;
//Loop over the string using iterator
for (it = s.begin(); it != s.end(); it++)
cout << *it;
cout <<endl;
return 0;
}
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Output:
GeeksforGeeks

Some of the most-used methods of the string class with example usage is given below:
  • begin: Returns an iterator to the first character of the string.
    #include <bits/stdc++.h>
    using namespace std;
    int main()
    {
    string s = "GeeksforGeeks";
    cout << "Print 1st character: " << *s.begin() << endl;
    return 0;
    }
    הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    Output:
    Print 1st character: G
  • end: Returns an iterator to the character following the last character of the string. This character acts as a placeholder and accessing it results in undefined behaviour.
    #include <bits/stdc++.h>
    using namespace std;
    int main()
    {
    string s = "GeeksforGeeks";
    //s.end() access is invalid, so we
    //do as s.end() - 1, to get the iterator
    //pointing at the last character
    cout << *(s.end() - 1) << endl;
    return 0;
    }
    הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    Output:
    s
  • size: Returns the no. of characters in the string. Same as using length().
  • clear: Removes all the characters from the string, thus making it an empty string ("")
  • empty: Returns a boolean indicating whether string is empty.
    #include <bits/stdc++.h>
    using namespace std;
    int main()
    {
    string s = "GeeksforGeeks";
    cout << "Length of String: " << s.size() << endl;
    //Clear out the given string
    s.clear();
    //Check if empty
    if (s.empty())
    cout << "String is empty\n";
    return 0;
    }
    הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    Output:
    Length of String: 13
    String is empty
  • insert: Insert another string at a certain position. insert takes 2 arguments (position, string-to-insert) as shown in the example below.
    #include <bits/stdc++.h>
    using namespace std;
    int main()
    {
    string s1 = "Hello Everyone";
    string s2 = "and Good Day to ";
    //Insert s2 at index 6 of s1
    s1.insert(6, s2);
    cout << s1 << endl;
    return 0;
    }
    הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    Output:
    Hello and Good Day to Everyone
  • push_back: Append a character to end of string
  • pop_back: Remove a character from the end.
    #include <bits/stdc++.h>
    using namespace std;
    int main()
    {
    string str = "abc";
    //Append character 'd' to end
    str.push_back('d');
    cout << str << endl;
    //Remove last character
    str.pop_back();
    cout << str << endl;
    return 0;
    }
    הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    Output:
    abcd
    abc
  • find: Find occurence of one string in another. If string is found, the position of occurence is returned, else string::npos is returned (indicating not-found).
    #include <bits/stdc++.h>
    using namespace std;
    int main()
    {
    string s1 = "GeeksforGeeks";
    string s2 = "for";
    string s3 = "abc";
    //Returns 5 as 'for' is found at
    //index 5 in s1
    cout << s1.find(s2) << endl;
    //s3 is not present in s1
    //so it return npos
    if (s1.find(s3) == string::npos)
    cout << "String '" << s3 << "' not found\n";
    return 0;
    }
    הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    Output:
    5
    String 'abc' not found
  • substr: Generate substring from string. It takes two arguments (position, no. of characters). Generates a substring from [position:position+num_characters-1]. However, the 2nd argument is optional, meaning if not provided substring is generated till end-of string.
    #include <bits/stdc++.h>
    using namespace std;
    int main()
    {
    string s = "GeeksforGeeks";
    //1st argument is: position
    //2nd argument is: no. of characters
    cout << s.substr(5, 3) << endl;
    //If 2nd argument is not provided, substring
    // is generated from position to end to string
    cout << s.substr(5) << endl;
    return 0;
    }
    הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    Output:
    for
    forGeeks
The following are some basic implementation problems covering the topics discussed until now.

  • Problem 1) Count the number of digits of a number.
    #include <bits/stdc++.h>
    using namespace std;
    int main()
    {
    unsigned long long int x = 255657434267;
    int num_digits = 0;
    do {
    num_digits++;
    x /= 10;
    }
    while (x);
    cout << num_digits << endl;
    return 0;
    }
    הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    Output:
    12
    We have used the do-while loop for the particular problem because we should still increment the count when the user inputs 0. If we had used while loop, then the loop would break immediately. (while(0) ~ while(false)). Inside the loop statement, we increment count by 1 and successively divide by 10. By the time x becomes 0, num_digits equals the number of digits.

  • Problem 2) Write a program simulating a calculator (supporting +,-,*,/). It should continuously ask for 2 numbers and the particular operation to perform (as a character), and produce the output accordingly. The program should quit if the user enters the character 'Q'.
    #include <bits/stdc++.h>
    using namespace std;
    int main()
    {
    //opr ~ operation to perform
    //op1 ~ operand 1
    //op2 ~ operand 2
    //OUTPUT: (op1 opr op2)
    char opr;
    int op1, op2;
    while (true) {
    cin >> opr;
    if (opr == 'Q')
    break;
    else {
    cin >> op1 >> op2;
    switch(opr) {
    case '+':
    cout << op1 + op2 << endl;
    break;
    case '-':
    cout << op1 - op2 << endl;
    break;
    case '*':
    cout << op1 * op2 << endl;
    break;
    הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    Input
    + 4 5
    * 2 3
    Q
    - 5 4
    Complete Code/Output
    #include <bits/stdc++.h>
    using namespace std;
    
    int main()
    {
        //opr ~ operation to perform
        //op1 ~ operand 1
        //op2 ~ operand 2
        //OUTPUT: (op1 opr op2)
        char opr;
        int op1, op2;
        
        while (true) {
            
            cin >> opr;
            
            if (opr == 'Q')
                break;
            else {
                cin >> op1 >> op2;
                switch(opr) {
                    case '+':
                        cout << op1 + op2 << endl;
                        break;
                    case '-':
                        cout << op1 - op2 << endl;
                        break;
                    case '*':
                        cout << op1 * op2 << endl;
                        break;
                    case '/':
                        cout << op1 / op2 << endl;
                        break;
                    default:
                        cout << "Invalid Operator\n";
                        break;
                }
            }
        }
        
        return 0;
    }
    
    9
    6
    Explanation: The above code combines the concepts of while loop and switch-case. while(true) allows us to run the program indefinitely, asking for continuous user input. Once, the user enters an operator, we fall-back to the if-part and further ask the operands, then we perform the calculation and print the result, otherwise, if the user enters the character 'Q', then the infinite-loop breaks, quitting the calculator program. As the sample input/output shows, we perform 4+5 and 2*3, but when we hit Q, we quit and skip the calculation of 5-4.

  • Problem 3) Take as input n numbers and find the average.
    #include <bits/stdc++.h>
    using namespace std;
    int main()
    {
    //the number of array elements
    int n = 6;
    int arr[] = {2,3,1,5,6,8};
    int sum = 0;
    for (int i=0; i<n; i++)
    sum += arr[i];
    cout << 1.0*sum/n;
    return 0;
    }
    הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    Output:
    4.16667
    In the above program, we take as input n numbers and store them in an array to find the average. Note however that average can be a floating-point value. Thus while printing the output we need to type-cast it to a double, which we do as 1.0*sum/n. This implicitly converts to double after multiplying by 1.0.

  • Problem 4) Check if a string entered is a palindrome or not. (A palindrome is a string which is the same as the original when reversed)
    #include <bits/stdc++.h>
    using namespace std;
    void check_palindrome(string s)
    {
    int len = s.length();
    for (int i=0; i<len; i++)
    if (s[i] != s[len-i-1]) {
    cout << "string " + s + " is not a palindrome\n";
    return;
    }
    cout << "string " + s + " is a palindrome\n";
    }
    int main()
    {
    string s1 = "kayak", s2 = "kappa";
    check_palindrome(s1);
    check_palindrome(s2);
    return 0;
    }
    הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    Output:
    string kayak is a palindrome
    string kappa is not a palindrome
    For palindrome checking, we need to check whether 1st character and last character match, then 2nd character and 2nd to last character and so on. Generalising, the ith character should match the (len-i-1)th character (0-indexing), where len is the length of the string.

  • Problem 5) Convert decimal number input by the user to binary.
    #include <bits/stdc++.h>
    using namespace std;
    int main()
    {
    long long x = 29;
    string bin;
    while (x) {
    bin += (char)((x & 1) + '0');
    x >>= 1;
    }
    reverse(bin.begin(), bin.end());
    cout << bin << endl;
    return 0;
    }
    הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    Output:
    11101
    The above program is a bit complicated hence needs explanation. Since the Binary form of a number is represented by 0s and 1s, hence for a large decimal number (having 10-15 digits), it might not be even accommodable by unsigned long long int. Hence, we use string to store the answer. The expression (x & 1) finds out whether the remainder when it is divisible by 2. If yes, the remainder is 0, otherwise 1. We append this value after adding ASCII '0' to the binary string and typecasting to char. At each step, we further divide x by 2 by right-shift-1. Finally, we reverse the binary string to get the desired result.
Pointers are symbolic representation of addresses. They enable programs to simulate call-by-reference as well as to create and manipulate dynamic data structures. It’s general declaration in C/C++ has the format:

Syntax:
datatype *var_name; 
int *ptr; //ptr can point to an address which holds int data



How to use a pointer?
  • Define a pointer variable
  • Assigning the address of a variable to a pointer using unary operator (&) which returns the address of that variable.
  • Accessing the value stored in the address using unary operator (*) which returns the value of the variable located at the address specified by its operand.
The reason we associate data type to a pointer is that it knows how many bytes the data is stored in. When we increment a pointer, we increase the pointer by the size of data type to which it points.

pointers in c
// C++ program to illustrate Pointers in C++
#include <bits/stdc++.h>
using namespace std;
void geeks()
{
int var = 20;
// declare pointer variable
int* ptr;
// note that data type of ptr and var must be same
ptr = &var;
// assign the address of a variable to a pointer
cout << "Value at ptr = " << ptr << "\n";
cout << "Value at var = " << var << "\n";
cout << "Value at *ptr = " << *ptr << "\n";
}
// Driver program
int main()
{
geeks();
}
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Output:
Value at ptr = 0x7ffdcf42ad9c
Value at var = 20
Value at *ptr = 20

References in C++

C++ References is a new language construct which was introduced to reduce the dependency over pointers for doing indirect memory access. Usage of pointers requires caution as the programmer needs to manually deallocate them to avoid memory leaks. A reference is an alternative name for a memory location. References are useful in following situations -
  1. Modify the passed parameters in a function
    #include <bits/stdc++.h>
    using namespace std;
    void swap (int& first, int& second)
    {
    int temp = first;
    first = second;
    second = temp;
    }
    int main()
    {
    int a = 2, b = 3;
    swap(a, b);
    cout << a << " " << b;
    return 0;
    }
    הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    Output
    3 2
  2. Avoiding copy of large structures
    struct Student {
    string name;
    string address;
    int rollNo;
    }
    void print(const Student &s)
    {
    cout << s.name << " " << s.address << " " << s.rollNo;
    }
    הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
  3. In For-Each Loops to modify all objects
    #include <bits/stdc++.h>
    using namespace std;
    int main()
    {
    vector<int> vect{ 10, 20, 30, 40 };
    for (int &x : vect)
    x = x + 5;
    for (int x : vect)
    cout << x << " ";
    return 0;
    }
    הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

  4. References vs Pointers
    1. A pointer can be declared as VOID but a reference can't. It must refer to some existing variable/memory location. Also, references can't be assigned NULL unlike pointers.
    2. References are less powerful than pointers
      • Once a Reference is created, it can't be made to refer another variable. With pointers we can do so.
      • A reference must be initialized. Pointers can be declared without initialization.

    Types of Function Call (References v/s Pointers)

    There are 3 ways to pass C++ arguments to a function:
    • call-by-value
    • call-by-reference with pointer argument
    • call-by-reference with reference argument

    // C++ program to illustrate call-by-methods in C++
    #include <bits/stdc++.h>
    using namespace std;
    // Pass-by-Value
    int square1(int n)
    {
    // Address of n in square1() is not the same as n1 in main()
    cout << "address of n1 in square1(): " << &n << "\n";
    // clone modified inside the function
    n *= n;
    return n;
    }
    // Pass-by-Reference with Pointer Arguments
    void square2(int* n)
    {
    // Address of n in square2() is the same as n2 in main()
    cout << "address of n2 in square2(): " << n << "\n";
    // Explicit de-referencing to get the value pointed-to
    *n *= *n;
    }
    // Pass-by-Reference with Reference Arguments
    void square3(int& n)
    {
    // Address of n in square3() is the same as n3 in main()
    הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    Complete Code/Output:
    // C++ program to illustrate call-by-methods in C++
    
    #include <bits/stdc++.h>
    using namespace std;
    
    // Pass-by-Value
    int square1(int n)
    {
        // Address of n in square1() is not the same as n1 in main()
        cout << "address of n1 in square1(): " << &n << "\n";
    
        // clone modified inside the function
        n *= n;
        return n;
    }
    
    // Pass-by-Reference with Pointer Arguments
    void square2(int* n)
    {
        // Address of n in square2() is the same as n2 in main()
        cout << "address of n2 in square2(): " << n << "\n";
    
        // Explicit de-referencing to get the value pointed-to
        *n *= *n;
    }
    
    // Pass-by-Reference with Reference Arguments
    void square3(int& n)
    {
        // Address of n in square3() is the same as n3 in main()
        cout << "address of n3 in square3(): " << &n << "\n";
    
        // Implicit de-referencing (without '*')
        n *= n;
    }
    
    void geeks()
    {
        // Call-by-Value
        int n1 = 8;
        cout << "address of n1 in main(): " << &n1 << "\n";
        cout << "Square of n1: " << square1(n1) << "\n";
        cout << "No change in n1: " << n1 << "\n";
    
        // Call-by-Reference with Pointer Arguments
        int n2 = 8;
        cout << "address of n2 in main(): " << &n2 << "\n";
        square2(&n2);
        cout << "Square of n2: " << n2 << "\n";
        cout << "Change reflected in n2: " << n2 << "\n";
    
        // Call-by-Reference with Reference Arguments
        int n3 = 8;
        cout << "address of n3 in main(): " << &n3 << "\n";
        square3(n3);
        cout << "Square of n3: " << n3 << "\n";
        cout << "Change reflected in n3: " << n3 << "\n";
    }
    
    // Driver program
    int main()
    {
        geeks();
    }
    address of n1 in main(): 0x7ffec6732e4c
    address of n1 in square1(): 0x7ffec6732e2c
    Square of n1: 64
    No change in n1: 8
    address of n2 in main(): 0x7ffec6732e50
    address of n2 in square2(): 0x7ffec6732e50
    Square of n2: 64
    Change reflected in n2: 64
    address of n3 in main(): 0x7ffec6732e54
    address of n3 in square3(): 0x7ffec6732e54
    Square of n3: 64
    Change reflected in n3: 64

    In C++, by default arguments are passed by value and the changes made in the called function will not reflect in the passed variable. The changes are made into a clone made by the called function.
    If wish to modify the original copy directly (especially in passing huge object or array) and/or avoid the overhead of cloning, we use pass-by-reference. Pass-by-Reference with Reference Arguments does not require any clumsy syntax for referencing and dereferencing.

    Array Name as Pointers

    An array name contains the address of first element of the array which acts like constant pointer. It means, the address stored in array name can't be changed.
    For example, if we have an array named val then val and &val[0] can be used interchangeably.

    // C++ program to illustrate Array Name as Pointers in C++
    #include <bits/stdc++.h>
    using namespace std;
    void geeks()
    {
    // Declare an array
    int val[3] = { 5, 10, 20 };
    // declare pointer variable
    int* ptr;
    // Assign the address of val[0] to ptr
    // We can use ptr=&val[0];(both are same)
    ptr = val;
    cout << "Elements of the array are: ";
    cout << ptr[0] << " " << ptr[1] << " " << ptr[2];
    }
    // Driver program
    int main()
    {
    geeks();
    }
    הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    Output:
    Elements of the array are: 5 10 20

    Untitled presentation (2) If pointer ptr is sent to a function as an argument, the array val can be accessed in a similar fashion.

    Pointers and String literals

    String literals are arrays containing null-terminated character sequences. String literals are arrays of type character plus terminating null-character, with each of the elements being of type const char (as characters of string can't be modified).
    const char * ptr = "geek";
    This declares an array with the literal representation for "geek", and then a pointer to its first element is assigned to ptr. If we imagine that "geek" is stored at the memory locations that start at address 1800, we can represent the previous declaration as:

    Screenshot (23)
    As pointers and arrays behave in the same way in expressions, ptr can be used to access the characters of string literal. For example:
    char x = *(ptr+3);
    char y = ptr[3];
    Here, both x and y contain k stored at 1803 (1800+3).

    Pointers to pointers

    In C++, we can create a pointer to a pointer that in turn may point to data or other pointer. The syntax simply requires the unary operator (*) for each level of indirection while declaring the pointer.
    char a;
    char *b;
    char ** c;
    a = ’g’;
    b = &a;
    c = &b;
    Here b points to a char that stores ‘g’ and c points to the pointer b.

    Void Pointers

    This is a special type of pointer available in C++ which represents absence of type. void pointers are pointers that point to a value that has no type (and thus also an undetermined length and undetermined dereferencing properties).
    This means that void pointers have great flexibility as it can point to any data type. There is payoff for this flexibility. These pointers cannot be directly dereferenced. They have to be first transformed into some other pointer type that points to a concrete data type before being dereferenced.

    // C++ program to illustrate Void Pointer in C++
    #include <bits/stdc++.h>
    using namespace std;
    void increase(void* data, int ptrsize)
    {
    if (ptrsize == sizeof(char)) {
    char* ptrchar;
    // Typecast data to a char pointer
    ptrchar = (char*)data;
    // Increase the char stored at *ptrchar by 1
    (*ptrchar)++;
    cout << "*data points to a char"
    << "\n";
    }
    else if (ptrsize == sizeof(int)) {
    int* ptrint;
    // Typecast data to a int pointer
    ptrint = (int*)data;
    // Increase the int stored at *ptrchar by 1
    (*ptrint)++;
    cout << "*data points to an int"
    << "\n";
    }
    }
    הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    Complete Code/Output:
    // C++ program to illustrate Void Pointer in C++
    #include <bits/stdc++.h>
    using namespace std;
    
    void increase(void* data, int ptrsize)
    {
        if (ptrsize == sizeof(char)) {
            char* ptrchar;
    
            // Typecast data to a char pointer
            ptrchar = (char*)data;
    
            // Increase the char stored at *ptrchar by 1
            (*ptrchar)++;
            cout << "*data points to a char"
                 << "\n";
        }
        else if (ptrsize == sizeof(int)) {
            int* ptrint;
    
            // Typecast data to a int pointer
            ptrint = (int*)data;
    
            // Increase the int stored at *ptrchar by 1
            (*ptrint)++;
            cout << "*data points to an int"
                 << "\n";
        }
    }
    
    void geek()
    {
        // Declare a character
        char c = 'x';
    
        // Declare an integer
        int i = 10;
    
        // Call increase function using a char and int address respectively
        increase(&c, sizeof(c));
        cout << "The new value of c is: " << c << "\n";
        increase(&i, sizeof(i));
        cout << "The new value of i is: " << i << "\n";
    }
    
    // Driver program
    int main()
    {
        geek();
    }
    *data points to a char
    The new value of c is: y
    *data points to an int
    The new value of i is: 11

    Invalid pointers

    A pointer should point to a valid address but not necessarily to valid elements (like for arrays). These are called invalid pointers. Uninitialized pointers are also invalid pointers.
    int *ptr1;
    int arr[10];
    int *ptr2 = arr+20;
    Here, ptr1 is uninitialized so it becomes an invalid pointer and ptr2 is out of bounds of arr so it also becomes an invalid pointer.
    (Note: invalid pointers do not necessarily raise compile errors)

    NULL Pointers

    Null pointer is a pointer which point nowhere and not just an invalid address.
    Following are 2 methods to assign a pointer as NULL;
    int *ptr1 = 0;
    int *ptr2 = NULL;

VOID Pointers

A void pointer is a pointer that doesn't have any type and thus can point to any data-type by explicit casting. Since the data-type this pointer refers to isn't defined upon declaration, we can't dereference a void pointer.
#include <bits/stdc++.h>
using namespace std;
int main()
{
int x = 5;
float f = 6.5;
string s = "Hello World";
void *p;
p = &x; //valid
p = &f; //valid
p = &s; //valid
cout << *p << endl;
cout << *(static_cast<string*>(p)) << endl;
}
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Generates the following error:
prog.cpp: In function 'int main()':
prog.cpp:17:14: error: 'void*' is not a pointer-to-object type
cout << *p << endl;
^
All the assignment statements are valid because a void pointer can be made to point to any data-type. However, the above code doesn't compile because of the line:
cout << *p << endl. The reason being, we tried to de-reference a void pointer without casting. The subsequent line prints the string: "Hello World" successfully.

NULL Pointers

A pointer declared a value always contains garbage value, thus pointing to a random location in memory. To signify a pointer as not pointing to any meaningful variable, we use the NULL Macro. NULL is a Macro defined in standard library, and it's value is generally implementation specific, but most compilers set it to value: 0. Thus, assigning NULL to a pointer, and putting it in an if-statement generates boolean-false (because of 0):
#include <bits/stdc++.h>
using namespace std;
int main()
{
int *p = NULL;
cout << p << endl;
if (p)
cout << "Pointer is not NULL\n";
else
cout << "Pointer is NULL\n";
}
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Output:
0
Pointer is NULL
Since NULL is a MACRO defined to have 0 value, it poses a problem in ambiguity issues of overloaded functions:
#include <bits/stdc++.h>
using namespace std;
void fun(int x) { cout << "Integer Call: " << x << endl; }
void fun(int *x) { cout << "Pointer Call: " << x << endl; }
int main()
{
int *p = NULL;
fun(0); //Integer Call: 0
fun(p); //Pointer Call: 0
fun(NULL); //ambiguity issue
return 0;
}
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Generates the following error:
prog.cpp: In function 'int main()':
prog.cpp:13:10: error: call of overloaded 'fun(NULL)' is ambiguous
fun(NULL); //ambiguity issue
^
prog.cpp:4:6: note: candidate: void fun(int)
void fun(int x) { cout << "Integer Call: " << x << endl; }
^
prog.cpp:5:6: note: candidate: void fun(int*)
void fun(int *x) { cout << "Pointer Call: " << x << endl; }
^
Since NULL is 0, it may mean int as well as int*, causing ambiguity. To fix this, C++ introduced nullptr pointer-literal keyword. In modern C++ usage, thus we set a pointer to nullptr instead of NULL, when we declare a pointer pointing to nothing. Same above code with the call: fun(nullptr) will not generated any errors as ambiguity is removed.
The following are some basic implementation problems covering the topics discussed until now.

  • Problem 1) Write a program to swap two numbers.
    #include <bits/stdc++.h>
    using namespace std;
    void swap(int &x, int &y)
    {
    int tmp = x;
    x = y;
    y = tmp;
    }
    int main()
    {
    int a = 5, b = 6;
    swap(a, b);
    cout << "Value of a: " << a << endl;
    cout << "Value of b: " << b << endl;
    return 0;
    }
    הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    Output:
    Value of a: 6
    Value of b: 5
    In the above program, we use C++ references and functions for swapping. When we pass a C++ reference to the function, it becomes call-by-reference, hence references of the actual variables get swapped thus reflecting the change is main() also.

  • Problem 2) Print a 2-D matrix, given the pointer to the 1st element and the matrix dimensions.
    #include <bits/stdc++.h>
    using namespace std;
    void print_matrix(int *p, int n, int m)
    {
    int i,j;
    for (i=0;i<n;i++) {
    for (j=0;j<m;j++)
    cout << *(p + i*m + j) << " ";
    cout << endl;
    }
    }
    int main()
    {
    int a[][4] = {
    {1, 2, 3, 4},
    {5, 6, 7, 8},
    {9, 10, 11, 12}
    };
    print_matrix((int*)a, 3, 4);
    return 0;
    }
    הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
    XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

    Output:
    1 2 3 4 
    5 6 7 8
    9 10 11 12
    In the above example, we print a 2-D matrix passed as a pointer to the function print_matrix. Since p is the pointer to the 1st element of the matrix, we can access the jth element of the ith row by shifting p by i*m times (i.e. each row contains m elements, so to reach row i, we need to move i*m times), then, to get to the jth element, we add j to p.

If you are facing any issue on this page. Please let us know.